package sg.edu.nus.iss.ooad.jass.ui;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import sg.edu.nus.iss.ooad.jass.controller.AdvertiserController;
import sg.edu.nus.iss.ooad.jass.controller.JobAdvertisementController;
import sg.edu.nus.iss.ooad.jass.entity.JobAdvertisement;
import sg.edu.nus.iss.ooad.jass.entity.LoginInfo;
import sg.edu.nus.iss.ooad.jass.ui.widget.AbstractJASSRegularWindow;
import sg.edu.nus.iss.ooad.jass.ui.widget.JASSRegularPanel;

/**
 *
 * This is Create Job Advertisement Form. it's used to add  a job advertisement.
 * user will use a form where the data can be entered. each job has a unique id, 
 * and is associated with a company, which is offerring the position.
 *
 * @author Isak Rabin (HT082193M)
 * @version 1.0
 * @since 1.0 
 *
 */
public class AdvertiserCreateJobAdvertisementForm extends AbstractJASSRegularWindow {

        private static final long serialVersionUID = -3826074276828003296L;
        private static final Logger logger = Logger.getLogger(AdvertiserCreateJobAdvertisementForm.class.getName());

        //Form Components
        private Label labelErrorMessage = null;
        private Label labelCompanyID = null;
        private Label labelStartDate = null;
        private Label labelFinishDate = null;
        private Label labelJobTitle = null;
        private Label labelJobDescription = null;
        private Label labelJobLocation = null;
        private Label labelJobStartDate = null;
        private Label labelCompanyDepartment = null;
        private Label labelTechnicalSkills = null;
        private Label labelManagementSkills = null;
        private Label labelMinSalary = null;
        private Label labelMaxSalary = null;
        private TextField textCompanyID = null;
        private TextField textStartDate = null;
        private TextField textFinishDate = null;
        private TextField textJobTitle = null;
        private TextArea textJobDescription = null;
        private TextField textJobLocation = null;
        private TextField textJobStartDate = null;
        private TextField textCompanyDepartment = null;
        private TextArea textTechnicalSkills = null;
        private TextArea textManagementSkills = null;
        private TextField textMinSalary = null;
        private TextField textMaxSalary = null;
        private Button btnSearchCompany = null;
        private Button btnCreate = null;
        private Button btnCancel = null;
        private Button btnReset = null;
        private JASSRegularPanel formPanel = null;
        private Panel inputPanel = null;
        private Panel buttonPanel = null;
        private GridBagLayout inputLayout = null;

        //Form parent
        private AbstractJASSRegularWindow parent = null;
        private Label labelCompanyName = null;

        //Singleton Object
        private static AdvertiserCreateJobAdvertisementForm instance;
        
       /**
        * Constructor of AdvertiserCreateJobAdvertisementForm with parameter of AbstractJASSRegularWindow
        * @param parent
        */
        private AdvertiserCreateJobAdvertisementForm(AbstractJASSRegularWindow parent) {
                super("Job Advertisement and Search System", new Dimension(550, 400));
                setResizable(false);
                initComponents();
                this.parent = parent;
        }

        /**
         * Singleton method to initialize the AdvertiserCreateJobAdvertisementForm .
         * @param parent
         * @return instance of AdvertiserCreateJobAdvertisementForm
         */
        public static AdvertiserCreateJobAdvertisementForm getInstance(AbstractJASSRegularWindow parent) {
                if (instance == null) {
                        instance = new AdvertiserCreateJobAdvertisementForm(parent);
                }
                return instance;
        }

        /**
         * This is to set company id to textbox of company ID.
         * @param companyID
         */
        public void setCompanyId(String companyID) {
                textCompanyID.setText(companyID);
        }

        /**
         * This is to set company name to label of the company name
         * @param companyName
         */
        public void setCompanyName(String companyName) {
                labelCompanyName.setText(companyName);
        }

      /**
       * This is to initialize all the component within the form.
       */
        private void initComponents() {
                //initiate all Components
                labelErrorMessage = new Label("", Label.LEFT);
                labelErrorMessage.setForeground(Color.RED);
                labelCompanyID = new Label("Company ID", Label.LEFT);
                labelCompanyName = new Label("Company Name ", Label.LEFT);
                labelStartDate = new Label("Ads. Start Date (dd/MM/yyyy)", Label.LEFT);
                labelFinishDate = new Label("Ads. Finish Date (dd/MM/yyyy)", Label.LEFT);
                labelJobTitle = new Label("Job Title", Label.LEFT);
                labelJobDescription = new Label("Job Description", Label.LEFT);
                labelJobLocation = new Label("Job Location", Label.LEFT);
                labelJobStartDate = new Label("Job Start Date (dd/MM/yyyy)", Label.LEFT);
                labelCompanyDepartment = new Label("Company Department", Label.LEFT);
                labelTechnicalSkills = new Label("Technical Skills", Label.LEFT);
                labelManagementSkills = new Label("Management Skills", Label.LEFT);
                labelMinSalary = new Label("Min. Salary", Label.LEFT);
                labelMaxSalary = new Label("Max. Salary", Label.LEFT);
                textCompanyID = new TextField(5);
                textStartDate = new TextField(15);
                textFinishDate = new TextField(15);
                textJobTitle = new TextField(35);
                textJobDescription = new TextArea(5, 35);
                textJobLocation = new TextField(35);
                textJobStartDate = new TextField(15);
                textCompanyDepartment = new TextField(35);
                textTechnicalSkills = new TextArea(5, 25);
                textManagementSkills = new TextArea(5, 25);
                textMinSalary = new TextField(15);
                textMaxSalary = new TextField(15);
                btnSearchCompany = new Button("...");
                btnCreate = new Button("Create");
                btnCancel = new Button("Cancel");
                btnReset = new Button("Reset");
                buttonPanel = new Panel();
                inputPanel = new Panel();
                formPanel = new JASSRegularPanel("Create Job Advertisement");

                //set the action listener
                btnSearchCompany.addActionListener(new SearchCompanyActionListener());
                btnCreate.addActionListener(new CreateActionListener());
                btnCancel.addActionListener(new CancelActionListener());
                btnReset.addActionListener(new ResetActionListener());

                //set Layout
                buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
                buttonPanel.add(btnCreate);
                buttonPanel.add(btnReset);
                buttonPanel.add(btnCancel);

                inputLayout = new GridBagLayout();
                inputPanel.setLayout(inputLayout);

                attachComponent(labelErrorMessage, 0, 0, 8, 1);
                attachComponent(labelCompanyID, 0, 1, 1, 1);
                attachComponent(textCompanyID, 1, 1, 1, 1);
                attachComponent(btnSearchCompany, 2, 1, 1, 1);
                attachComponent(labelCompanyName, 1, 2, 1, 1); 
                attachComponent(labelStartDate, 6, 1, 1, 1);
                attachComponent(textStartDate, 7, 1, 2, 1);
                attachComponent(labelFinishDate, 6, 2, 1, 1);
                attachComponent(textFinishDate, 7, 2, 2, 1);
                attachComponent(labelJobTitle, 0, 3, 1, 1);
                attachComponent(textJobTitle, 1, 3, 8, 1);
                attachComponent(labelJobDescription, 0, 4, 1, 1);
                attachComponent(textJobDescription, 1, 4, 8, 4);
                attachComponent(labelJobLocation, 0, 8, 1, 1);
                attachComponent(textJobLocation, 1, 8, 6, 1);
                attachComponent(labelJobStartDate, 0, 9, 1, 1);
                attachComponent(textJobStartDate, 1, 9, 5, 1);
                attachComponent(labelCompanyDepartment, 0, 10, 1, 1);
                attachComponent(textCompanyDepartment, 1, 10, 7, 1);
                attachComponent(labelTechnicalSkills, 0, 11, 1, 1);
                attachComponent(textTechnicalSkills, 1, 11, 8, 4);
                attachComponent(labelManagementSkills, 0, 15, 1, 1);
                attachComponent(textManagementSkills, 1, 15, 8, 4);
                attachComponent(labelMinSalary, 0, 19, 1, 1);
                attachComponent(textMinSalary, 1, 19, 1, 1);
                attachComponent(labelMaxSalary, 2, 19, 1, 1);
                attachComponent(textMaxSalary, 3, 19, 1, 1); 
                formPanel.add(inputPanel, BorderLayout.CENTER);
                formPanel.add(buttonPanel, BorderLayout.SOUTH);

                //add to the frame
                add(formPanel);
                pack();
        }


        /**
         * This function is to attach the component to the specified layout of the panel. 
         * @param c
         * @param gridx
         * @param gridy
         * @param gridwidth
         * @param gridheight
         * @param fill
         */

        @Override
        public void attachComponent(Component c, int gridx, int gridy, int gridwidth, int gridheight, int fill) {
                GridBagConstraints constraint = new GridBagConstraints();
                constraint.gridx = gridx;
                constraint.gridy = gridy;
                constraint.gridwidth = gridwidth;
                constraint.gridheight = gridheight;
                constraint.fill = fill;
                constraint.insets = new Insets(4, 4, 4, 4);
                constraint.weightx = 1.0;
                constraint.weighty = 1.0;
                inputPanel.add(c);
                inputLayout.setConstraints(c, constraint);
        }

        /**
         * This function is to reset initial value for each text field.
         */

        @Override
        public void resetForm() {
                textCompanyID.setText("");
                textStartDate.setText("");
                textFinishDate.setText("");
                textJobTitle.setText("");
                textJobDescription.setText("");
                textJobLocation.setText("");
                textJobStartDate.setText("");
                textCompanyDepartment.setText("");
                textTechnicalSkills.setText("");
                textManagementSkills.setText("");
                textMinSalary.setText("");
                textMaxSalary.setText("");
                labelCompanyName.setText("");
        }

        /**
         * Create Action Handler. Called when the user click button "Create".
         */
        class CreateActionListener implements ActionListener {

                private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");

                public void actionPerformed(ActionEvent e) {

                        //get all the input
                        String companyID = textCompanyID.getText();
                        String startDate = textStartDate.getText();
                        String finishDate = textFinishDate.getText();
                        String jobTitle = textJobTitle.getText();
                        String jobDescription = textJobDescription.getText();
                        String jobLocation = textJobLocation.getText();
                        String jobStartDate = textJobStartDate.getText();
                        String jobCompanyDepartment = textCompanyDepartment.getText();
                        String jobTechnicalSkills = textTechnicalSkills.getText();
                        String jobManagementSkills = textManagementSkills.getText();
                        String jobMinSalary = textMinSalary.getText();
                        String jobMaxSalary = textMaxSalary.getText();

                        //do validation
                        if (null == companyID || "".equalsIgnoreCase(companyID)) {
                                labelErrorMessage.setText("Please provide Company ID");
                                return;
                        }

                        if (null == startDate || "".equalsIgnoreCase(startDate)) {
                                labelErrorMessage.setText("Please provide Job Advertisement Start Date");
                                return;
                        } else if (startDate.length() != dateFormat.toPattern().length()) {
                                labelErrorMessage.setText("Incorrect Date format for Job Advertisement Start Date");
                                return;
                        } else {
                                dateFormat.setLenient(false);
                                try {
                                        //parse the startDate parameter
                                        dateFormat.parse(startDate.trim());
                                } catch (ParseException pe) {
                                        labelErrorMessage.setText(pe.getMessage());
                                        return;
                                }
                        }

                        if (null == finishDate || "".equalsIgnoreCase(finishDate)) {
                                labelErrorMessage.setText("Please provide Job Advertisement Finish Date");
                                return;
                        } else if (finishDate.length() != dateFormat.toPattern().length()) {
                                labelErrorMessage.setText("Incorrect Date format for Job Advertisement Finish Date");
                                return;
                        } else {
                                dateFormat.setLenient(false);
                                try {
                                        //parse the finishDate parameter
                                        dateFormat.parse(finishDate.trim());
                                } catch (ParseException pe) {
                                        labelErrorMessage.setText(pe.getMessage());
                                        return;
                                }
                        }


                        if (null == jobTitle || "".equalsIgnoreCase(jobTitle)) {
                                labelErrorMessage.setText("Please provide Job Advertisement Title");
                                return;
                        }

                        if (null == jobDescription || "".equalsIgnoreCase(jobDescription)) {
                                labelErrorMessage.setText("Please provide Job Advertisement Title");
                                return;
                        }


                        if (null == jobStartDate || "".equalsIgnoreCase(jobStartDate)) {
                                labelErrorMessage.setText("Please provide Job Start Date");
                                return;
                        } else if (jobStartDate.length() != dateFormat.toPattern().length()) {
                                labelErrorMessage.setText("Incorrect Date format for Job Start Date");
                                return;
                        } else {
                                dateFormat.setLenient(false);
                                try {
                                        //parse the startDate parameter
                                        dateFormat.parse(jobStartDate.trim());
                                } catch (ParseException pe) {
                                        labelErrorMessage.setText(pe.getMessage());
                                        return;
                                }
                        }

                        if (null == jobMinSalary || "".equalsIgnoreCase(jobMinSalary)) {
                                jobMinSalary = "0";
                        }

                        float minSalary = 0f;
                        if (jobMinSalary != null) {
                                try {
                                        minSalary = Float.parseFloat(jobMinSalary);
                                } catch (NumberFormatException nfx) {
                                        labelErrorMessage.setText(nfx.getMessage());
                                        return;
                                }
                        }

                        if (null == jobMaxSalary || "".equalsIgnoreCase(jobMaxSalary)) {
                                jobMaxSalary = "0";
                        }

                        float maxSalary = 0f;
                        if (jobMaxSalary != null) {
                                try {
                                        maxSalary = Float.parseFloat(jobMaxSalary);
                                } catch (NumberFormatException nfx) {
                                        labelErrorMessage.setText(nfx.getMessage());
                                        return;
                                }
                        }


                        //save it
                        JobAdvertisement jobAdvertisement = new JobAdvertisement();
                        jobAdvertisement.setJobTitle(jobTitle);
                        jobAdvertisement.setJobDescription(jobDescription);
                        jobAdvertisement.setJobLocation(jobLocation);
                        jobAdvertisement.setStartDate(startDate);
                        jobAdvertisement.setFinishDate(finishDate);
                        jobAdvertisement.setCompanyDepartment(jobCompanyDepartment);
                        jobAdvertisement.setTechnicalSkills(jobTechnicalSkills);
                        jobAdvertisement.setManagementSkills(jobManagementSkills);
                        jobAdvertisement.setMinSalary(minSalary);
                        jobAdvertisement.setMaxSalary(maxSalary);
                        jobAdvertisement.setCompanyID(companyID);
                        jobAdvertisement.setJobStartDate(jobStartDate);
                        JobAdvertisementController jobadvertisementController = new JobAdvertisementController();

                        boolean success = false;
                        AdvertiserController  advertiserController = new AdvertiserController();
                        try {
                                jobAdvertisement.setAdvertiserID(advertiserController.getAdvertiserByUserID(LoginInfo.getLoginId()).getID());
                                success = jobadvertisementController.createJobAdvertisement(jobAdvertisement);
                        } catch (Exception ex) {
                                logger.log(Level.SEVERE, null, ex);
                        }

                        if (success) {
                                displayMessage("Information", "Job advertisement has successfully create");
                                parent.resetForm();
                                close();
                        } else {
                                displayMessage("Error", "Failed to create Job advertisement.");
                        }
                }
        }

        /**
         * Cancel Action Handler. It is called when the user click button "Cancel"
         */
        class CancelActionListener implements ActionListener {

                public void actionPerformed(ActionEvent e) {
                        close();
                }
        }

        /**
         * Reset Form Action Handler. It is called when the user click button "Reset".
         */
        class ResetActionListener implements ActionListener {

                public void actionPerformed(ActionEvent e) {
                       resetForm();
                }
        }

        /**
         * Search Action Handler. It is called when the user click the button
         * to search Company.
         */
        class SearchCompanyActionListener implements ActionListener {
                public void actionPerformed(ActionEvent e) {
                        AdvertiserListCompanyForm companyForm = AdvertiserListCompanyForm.getInstance(AdvertiserCreateJobAdvertisementForm.this);
                        companyForm.setVisible(true);
                }
        } 
}
